#
#  Copyright (C) 2009 GSyC/LibreSoft
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU Affero General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU Affero General Public License for more details.
#
#	You should have received a copy of the GNU Affero General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 
#	Author : Jose Antonio Santos Cadenas <jcaden __at__ gsyc __dot__ es>
#

from django.contrib.gis.geos import Point
from django.contrib.gis.measure import D 

from social.privacy.utils import is_allowed

from datetime import datetime
from models import Social_node, Tag, Comment, Person
from utils import get_person

def set_tag(nodeid, tags):
	"""
	Sets new tags to the social node
	
	@param nodeid: (int) with the node id
	@param tags: (str) A string with all the tags separated by spaces
	
	@return: a tuple (bool, str) with the result (correct or not) and a description
	"""
	try:
		node=Social_node.objects.get(id=nodeid)
	except:
		return False, "Node doesn't exist"
	for tag in tags.split():
		tag_obj, created=Tag.objects.get_or_create(tag=tag)
		node.tags.add(tag_obj)
	return True, "No error"

def remove_tag(nodeid, tags):
	"""
	Removes tags from the social node
	
	@param nodeid: (int) with the node id
	@param tags: (str) A string with all the tags separated by spaces
	
	@return: a tuple (bool, str) with the result (correct or not) and a description
	"""
	try:
		node=Social_node.objects.get(id=nodeid)
	except:
		return False, "Node doesn't exist"
	for tag in tags.split():
		try:
			tag_obj=Tag.objects.get(tag=tag)
			node.tags.remove(tag_obj)
		except:
			pass
	return True, "No error"

def set_coordinates(nodeid, latitude, longitude, **kargs):
	"""
	Sets the position of any type of social_node
	"""
	try:
		n = Social_node.objects.get(pk=nodeid)
		n.position = Point(float(longitude), float(latitude), srid=4326)
		if "radius" in kargs:
			n.radius=float(kargs["radius"])
		if "altitude" in kargs:
			n.altitude = float(kargs["altitude"])
		n.pos_time = datetime.now()
		n.save()
		return True, "No error"
	except:
		return False, "The node doesn't exist"

def set_icon(nodeid, uri = None):
	"""
	Sets an icon uri for the node with nodeid
	"""
	try:
		node=Social_node.objects.get(id=nodeid)
	except:
		return False, "Node doesn't exist"
	
	if uri is not None:
		node.icon = uri
	else:
		node.icon = "defaultpath"

	return True, "No error"
	
def set_comment(nodeid, comment, author):
	"""
	Sets a comment made by author to the node with nodeid
	"""
	try:
		n = Social_node.objects.get(pk=nodeid)
	except:
		return False, "The node doesn't exist"
	try:
		a = Person.objects.get(pk=author)
	except:
		return False, "Author doesn't exist"
	if is_allowed(n.get_node(), a):
		c = Comment(node=n, author=a, comment=comment)
		c.save()
		return True, "Comment created correctly"
	else:
		return False, "You are not allowed to comment this node"

def delete_comment(commentid, userid):
	"""
	Deletes the comment from the node
	"""
	try:
		c = Comment.objects.get(id=commentid)
	except:
		return False, "Comment doesn't exist"
	try:
		p = Person.objects.get(id=userid)
	except:
		return False, "User doesn't exist"
	if p == c.author or p == c.node.get_owner():
		c.delete()
		return True, "No error"
	else:
		return False, "Only comment author and commented node owner can delete comments"

def get_comments(nodeid):
	"""
	Gets all comments for the node
	"""
	try:
		n = Social_node.objects.get(pk=nodeid)
	except:
		return False, "The node doesn't exist"
	comments = Comment.objects.filter(node=n)
	ret =  []
	for c in comments:
		ret.append(c.get_dictionary())
	return ret

def get_all(viewer=None):
	"""
	Returns an array with all the Social_nodes
	"""
	try:
		v=get_person(viewer)
		nodes_mod = Social_node.objects.all()
		nodes = []
		for node in nodes_mod:
			n = node.get_node().get_dictionary(v)
			nodes += [n]
		return nodes
	except:
		return []
	
def get_data(node_id, viewer=None):
	"""
	Returns the details for a node
	"""
	try:
		n = Social_node.objects.get(id=node_id)
		v=get_person(viewer)
		node = n.get_node().get_dictionary(viewer=v)
		return node
	except:
		return None

def get_nearby_node(nodeid, radius, viewer):
	"""
	Finds nodes in a radius (in km) from your position
	"""
	try:
		v = get_person(viewer)
		n = Social_node.objects.get(pk=nodeid)
		nodes = Social_node.objects.distance(n.position).order_by("distance").filter(position__distance_lte=(n.position, D(km=float(radius))))
		nds = []
		for node in nodes:
			try:
				n = node.get_node().get_dictionary(v)
				if n["position"]["distance"]:
					nds += [n]
			except:
				pass
		return nds
	except:
		return []
